-
-
Notifications
You must be signed in to change notification settings - Fork 142
feat(generator/console): add make:controller, make:model commands and the generator attribute #568
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(generator/console): add make:controller, make:model commands and the generator attribute #568
Conversation
|
@innocenzi For now, I'm not sure of the purpose of the |
|
@brendt are we good moving this outside the framework to the CLI project? |
innocenzi
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't tested this locally, but as I understand it, it will generate a controller in a predefined directory, right?
I don't really like this, personally, and I don't think it follows the philosophy of Tempest, where everything can be anywhere.
My implementation of tempest publish prompts the user every time for the path at which the file would be published. If the file already exists, the user is asked if the file should be replaced. What do you think of this approach?
src/Tempest/Console/src/Commands/Generators/MakeControllerCommand.php
Outdated
Show resolved
Hide resolved
src/Tempest/Console/src/Commands/Generators/MakeControllerCommand.php
Outdated
Show resolved
Hide resolved
src/Tempest/Console/src/Commands/Generators/MakeControllerCommand.php
Outdated
Show resolved
Hide resolved
You're right, this was the goal. No problem for me, I can follow your already approved work, I'll check how your command work ! |
Will discuss on Discord |
Pull Request Test Coverage Report for Build 11331827224Details
💛 - Coveralls |
|
Don't worry about commits, I've pulled the unmerged work of Enzo to refactor the code with its helpers on namespaces and Then I tried to stick as much as possible to the implementation of the |
|
As discussed in Discord here https://discord.com/channels/1236153076688359495/1295433932027990027/1298306566335893525 |
7fe30ac to
39b0ca9
Compare
brendt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My main concern is all the hoops we're jumping through to be able to return a StubFileGenerator from a command. There's a lot of complexity that comes with it, which could be avoided if we decide to rework the generator a bit, and instead inject it into the console command.
| - phpstan-baseline.neon | ||
| - vendor/phpat/phpat/extension.neon | ||
| - vendor/spaze/phpstan-disallowed-calls/extension.neon | ||
| - phpstan-baseline.neon |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why these changes?
| "composer phpstan" | ||
| ] | ||
| }, | ||
| "config": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you remove this? To make sure it doesn't get added again, rebase or merge main into your branch, then run composer up once more.
| $consoleCommandClass, | ||
| $inputBuilder->build(), | ||
| ); | ||
| $handler = ($consoleCommand instanceof GeneratorCommand) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this is the right way to go. I'd be very hesitant making changes within ExecuteConsoleCommand to accomodate for one specific command.
I still need to read through the rest though
| $targetPath = $this->promptTargetPath($suggestedPath); | ||
| $shouldOverride = $this->askForOverride($targetPath); | ||
|
|
||
| return new StubFileGenerator( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We talked about this briefly on Discord: I'm not convinced yet that we need a special kind of console commands that return a special kind of class. I rather just inject the generator into the console command.
Take, for example, a look at how the install command works: it doesn't need to return anything special, but rather passes the responsibility of actually installing a package to the underlying Installer class.
|
|
||
| final class MakeModelCommand | ||
| { | ||
| use HasGeneratorCommand; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This trait should be renamed to IsGeneratorCommand
| $this->assertMatchesSnapshot($class->print()); | ||
| } | ||
|
|
||
| #[Test] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the removal?
| * The values are the replacements for the placeholders (e.g. 'App\Models') | ||
| * @param bool $shouldOverride Whether the generator should override the file if it already exists. | ||
| */ | ||
| public function __construct( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason why this data is injected into the constructor instead of being passed to the generate method? Tempest tries to have all classes injectable, and aims to have a clear separation of data and functionality. When I see a "Stub File Generator", my assumption is that it's a class that I can inject and reuse, while its generate method would require me to pass in context-specific data.
Something like this:
$this->stubGenerator->generate($stub, $target, $replacements, $shouldOverwrite);There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is because atm the generator isn't a service but something like a DTO and the generate method is expected to be run once.
The instance is created and returned by the GeneratorCommand method handler.
In case, if we decide to change the overall approch this could be changed as you mention I guess 😄
| return $this->reflectionClass->getName(); | ||
| } | ||
|
|
||
| public function getFilePath(): string|false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's change this to string. It'll only return false if we're reflecting over internal PHP classes. I'd rather throw an exception in that case:
$path = $this->reflectionClass->getFileName();
if ($path === false)
{
// throw
}
return $path;There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll check this out because I don't remember tweaking on this, so maybe a vestige of the feat/publish
|
|
||
| public function __construct( | ||
| private PHPReflector|PHPReflectionType|string $reflector, | ||
| private PHPReflector|PHPReflectionType|string|null $reflector, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity: when does this happen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It happen to me weeks ago but if I remember correctly, an instance of the TypeReflector were created dynamically and something null passed in param so it throws an exception.
But giving "null" works.
|
|
||
| final readonly class PathHelper | ||
| { | ||
| public static function root(string ...$paths): string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need this one anymore. Use root_path() instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, i'll correct this ASAP
|
Let's close this one in favor of #647 |
This PR is a starting point of creating the
make commandsfor the framework using the internal Generation Component.Here's the related issue #472
It add a make:controller command
TestControllerlikeTestController.phpControllersdirectoryclassnamearg from the commandSo, for example if I have a project with a default autoloaded namespace from composer like :
my-project/app=>AppAnd I run
make:controller Admin/DashboardIt will generate a class named
DashboardControlleratmy-project/app/Controllers/Admin/DashboardController.phpAnd with the following namespace
App\Controllers\AdminNext steps before duplicate this into others make commands are :
MakeControllerCommandspecifics params like the route path and the view pathFor the 2 first TODOs I'm looking for ideas, if someone have any.